using DG.Tweening;
using GameFramework.Battle.Core;
using Gameplay.PVE.Config;
using Gameplay.PVE.Entity;
using Gameplay.PVE.TurnBase;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
using XLua;
using Yoozoo.Gta.Common;
using Random = UnityEngine.Random;

namespace Gameplay.PVE.Utils
{
    public class BattleLog
    {
        [Conditional("UNITY_EDITOR")]
        public static void UnitLog(UnitBase unit,object obj)
        {
            unit?.Log(obj);
        }
    }
    public class PveUtils
    {
        public static float GlobalDamage = 1;
        public static bool ShowAnimatorLog = false;
        public static bool HasShownSkillVideo = false;
        public static float globalRatio = 1f;

        public static bool ShowSearch = false;

        private static Dictionary<int, PveSkillConfig> skillConfigs;

        private static Dictionary<int, PveHeroConfig> heroConfigs;

        private static Dictionary<int, PveSkillBulletConfig> bulletConfigs;

        private static Dictionary<int, PveSkillElementConfig> elementConfigs;

        private static Dictionary<int, PveWeaponConfig> weaponConfigs;

        private static Dictionary<int, RpgSpecialObjectConfig> specialObjectConfigs;

        public static Dictionary<int, RpgResourceConfig> rpgResourceConfigs;

        public static Dictionary<int, List<RpgResourceConfig>> rpgKeyAndResourceConfigMap;


        public static Dictionary<int, RpgNpcevent> rpgNpcEventsConfig;

        public static Dictionary<int, RpgNpcdialogcontent> rpgNpcDialogContentConfig;

        private static Dictionary<int, Dictionary<int, RpgNpcdialog>> rpgNpcDialogConfig;

        private static Dictionary<int, RpgLevelMonsterConfig> rpgLevelMonsterConfigs;

        private static Dictionary<int,Dictionary<int, RpgModelPlaceConfig>> rpgModelPlaceConfigs;

        private static Dictionary<int, RpgEffectConfig> rpgEffectConfigs;

        private static Dictionary<int, RpgModelConfig> rpgModelConfigs;

        private static Dictionary<int, RpgMonsterConfig> rpgMonsterConfigs;

        private static Dictionary<int, ExternalHeroConfig> externalHeroConfig;

        private static Dictionary<int, RpgObstacleConfig> obstacleConfigs;

        private static Dictionary<int, RpgSummonConfig> summonConfigs;
        
        private static Dictionary<int, TbsHeroConfig> tbsHeroConfigs;

        private static Dictionary<int, TbsSkillConfig> tbsSkillConfigs;

        private static Dictionary<int, TbsSkillPlayerConfig> tbsSkillPlayerConfigs;

        private static Dictionary<int, TbsSkillBulletConfig> tbsBulletConfigs;

        private static Dictionary<int, TbsSkillElementConfig> tbsElementConfigs;

        private static Dictionary<string, string> langConfigs = new Dictionary<string, string>();
      
        //private static Dictionary<int, RpgLevelConfig> rpgLevelConfigs;

        //private static Dictionary<int, RpgObstacleBasic> rpgObstacleBasics;

        public static int defaultLayer;
        
        public static int blackScreenLayer;

        public static int pveUnitLayer;

        public static int pveCameraColliderLayer;

        public static int commanderHairLayer;
        
        public static int agentHairLayer;

        public static int pveLogicLayer
        {
            get { return ~ (1 << pveCameraColliderLayer); }
        }

        public delegate bool Comp<in T>(T x, T y);

        public static float fps = 30;

        public static float frameSpeed = 30;

        public static int GetPositionIdByDeckIndex(int deckIndex)
        {
            if (deckIndex == 0 || deckIndex == 11)
            {
                return 1;
            }
            else if (deckIndex == 1 || deckIndex == 12)
            {
                return 2;
            }
            else if (deckIndex == 2 || deckIndex == 14)
            {
                return 3;
            }
            else if (deckIndex == 3 || deckIndex == 15)
            {
                return 4;
            }
            else if (deckIndex == 4 || deckIndex == 16)
            {
                return 5;
            }
            return 0;
        }
        
        public static Vector3 GetRandomVector3(Vector3 start, Vector3 end)
        {
            return new Vector3(Random.Range(start.x,end.x),Random.Range(start.y,end.y),Random.Range(start.z,end.z));
        }

        public static float GetManhattanDistance(Vector3 start, Vector3 end)
        {
            return Mathf.Abs(start.x - end.x) + Mathf.Abs(start.z - end.z);
        }

        public static void Sort<T>(ref T[] array,Comp<T> sortAction)
        {
            for (int i = 0; i < array.Length; i++)
            {
                for (int j = i; j < array.Length; j++)
                {
                    if (sortAction(array[i], array[j]))
                    {
                        var temp = array[j];
                        array[j] = array[i];
                        array[i] = temp;
                    }
                }
            }
        }
        private static int getInt(LuaTable table,string key)
        {
            return table.ContainsKey(key)?table.Get<string,int>(key):0;
        }

        private static float getFloat(LuaTable table,string key)
        {
            return table.ContainsKey(key)?table.Get<string,float>(key):0;
        }

        private static void GetArray<T>(LuaTable table,string name,ref List<T> output)
        {
            var data = table.Get<string,LuaTable>(name);
            output.Clear();
            for (int i = 1; i <= data.Length; i++)
            {
                var item = data.Get<int,T>(i);
                output.Add(item);
            }
        }

        private static List<T> GetArray<T>(LuaTable table)
        {
            var list = new List<T>();
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int,T>(i);
                list.Add(item);
            }
            return list;
        }
        private static List<Vector2Int> GetArrayVector2Int(LuaTable table)
        {
            var list = new List<Vector2Int>();
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int, LuaTable>(i);
                list.Add(GetVector2Int(item));
            }
            return list;
        }
        private static List<Vector3> GetArrayVector3(LuaTable table)
        {
            var list = new List<Vector3>();
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int,LuaTable>(i);
                list.Add(GetVector3(item));
            }
            return list;
        }
        
        private static List<Vector3Int> GetArrayVector3Int(LuaTable table)
        {
            var list = new List<Vector3Int>();
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int,LuaTable>(i);
                list.Add(GetVector3Int(item));
            }
            return list;
        }

        /*private static void GetMap<T1,T2>(LuaTable table, string name,ref Dictionary<T1,T2> output)
        {
            var data = table.Get<string, Dictionary<T1,T2>>(name);
            output.Clear();
            foreach (var item in data)
            {
                output.Add(item.Key,item.Value);
            }
        }*/

        private static Dictionary<string,T> GetMap<T>(LuaTable table)
        {
            var dic = new Dictionary<string, T>();
            var it = table.GetKeys().GetEnumerator();
            while (it.MoveNext())
            {
                dic.Add(it.Current.ToString(),GetValue<T>(table,it.Current.ToString()));
            }

            return dic;
        }

        private static T GetValue<T>(LuaTable table, string key)
        {
            var type = typeof(T);
            if (table.ContainsKey(key))
            {
                return table.Get<string, T>(key);
            }
            else
            {
                //Debug.LogError(key);
                return default;
            }
        }

        private static Vector3Int GetVector3Int(LuaTable table)
        {
            int x = table.Length <= 0 ? 0 : table.Get<int, int>(1);
            int y = table.Length <= 1 ? 0 : table.Get<int, int>(2);
            int z = table.Length <= 2 ? 0 : table.Get<int, int>(3);
            return new Vector3Int(x,y,z);
        }
        
        private static Vector3 GetVector3(LuaTable table)
        {
            float x = table.Length <= 0 ? 0 : table.Get<int, float>(1);
            float y = table.Length <= 1 ? 0 : table.Get<int, float>(2);
            float z = table.Length <= 2 ? 0 : table.Get<int, float>(3);
            return new Vector3(x,y,z);
        }
        private static Vector2Int GetVector2Int(LuaTable table)
        {
            int x = table.Length <= 0 ? 0 : table.Get<int, int>(1);
            int y = table.Length <= 1 ? 0 : table.Get<int, int>(2);
            return new Vector2Int(x, y);
        }
        private static Vector2 GetVector2(LuaTable table)
        {
            float x = table.Length <= 0 ? 0 : table.Get<int, float>(1);
            float y = table.Length <= 1 ? 0 : table.Get<int, float>(2);
            return new Vector2(x, y);
        }
        
        private static object GetValue(LuaTable table,string key,Type type)
        {
            if (type == typeof(bool))
            {
                return GetValue<bool>(table, key);
            }
            else if (type == typeof(int))
            {
                return GetValue<int>(table,key);
            }
            else if (type == typeof(float))
            {
                return GetValue<float>(table,key);
            }
            else if (type == typeof(string))
            {
                return GetValue<string>(table,key);
            }
            var data = table.Get<string,LuaTable>(key);
            if (data == null)
            {
                return default;
            }
            if (type == typeof(Vector3))
            {
                return GetVector3(data);
            }
            else if (type == typeof(Vector3Int))
            {
                return GetVector3Int(data);
            }
            else if (type == typeof(List<float>))
            {
                return GetArray<float>(data);
            }
            else if (type == typeof(List<string>))
            {
                return GetArray<string>(data);
            }
            else if (type == typeof(List<Vector2Int>))
            {
                return GetArrayVector2Int(data);
            }
            else if (type == typeof(List<int>))
            {
                return GetArray<int>(data);
            }
            else if (type == typeof(List<Vector3>))
            {
                return GetArrayVector3(data);
            }
            else if (type == typeof(List<Vector3Int>))
            {
                return GetArrayVector3Int(data);
            }
            else if (type == typeof(Dictionary<string, float>))
            {
                return GetMap<float>(data);;
            }
            else if (type == typeof(Dictionary<string, int>))
            {
                return GetMap<int>(data);;
            }
            else if (type == typeof(Vector2Int))
            {
                return GetVector2Int(data); ;
            }
            else if (type == typeof(Vector2))
            {
                return GetVector2(data); ;
            }
            return default;
        }

   


        public class PveHeroData
        {
            public List<int> heroAttributes;
            public int level;
            public int star;
            public int skillInitiative;
            public int skillInitiativeLevel;
            public List<Vector2Int> passiveSkillLevels;
        }
        
        private static Dictionary<int, PveHeroData> heroAttributes = new Dictionary<int, PveHeroData>();
   
        private static Dictionary<int,Dictionary<int,List<int>>> monsterAttributes = new Dictionary<int, Dictionary<int, List<int>>>();
        private static Dictionary<int,List<int>> monsterSkillLevels = new Dictionary<int,List<int>>();
        public static List<int> monsterLevels = new List<int>();

        public static void HeroAttributeChanged(int id,LuaTable table)
        {

        }

        public static List<int> GetHeroAttributes(int heroId)
        {
            if (heroAttributes.TryGetValue(heroId, out var list))
            {
                return list.heroAttributes;
            }
            UnityEngine.Debug.LogError("找不到英雄属性 "+ heroId);
            var l = new List<int>();
            for (int i = 0; i < 14; i++)
            {
                l.Add(0);
            }

            l[0] = 1000;
            l[1] = 100;
            l[2] = 100;
            return l;
        }

        public static PveHeroData GetPveHeroData(int heroId)
        {
            if (heroAttributes.TryGetValue(heroId, out var list))
            {
                return list;
            }
            return null;
        }
        
        public static int GetHeroLevel(int heroId)
        {
            if (heroAttributes.TryGetValue(heroId, out var data))
            {
                return data.level;
            }
            return 1;
        }

        public static int GetHeroStar(int heroId)
        {
            if (heroAttributes.TryGetValue(heroId, out var data))
            {
                return data.star;
            }
            return 1;
        }

        public static RpgNpcevent GetNpcEvent(int id)
        {
            rpgNpcEventsConfig.TryGetValue(id, out var data);
            return data;
        }

        public static Dictionary<int,RpgNpcdialog> GetNpcDialog(int id)
        {
            rpgNpcDialogConfig.TryGetValue(id, out var data);
            return data;
        }
        public static RpgNpcdialogcontent GetNpcdialogContent(int id)
        {
            rpgNpcDialogContentConfig.TryGetValue(id, out var data);
            return data;
        }
        public static List<int> GetMonsterAttributes(int monsterId,int monsterLEvel)
        {
            if (monsterAttributes.TryGetValue(monsterId, out var list))
            {
                if (list.TryGetValue(monsterLEvel, out var attr))
                {
                    return attr;
                }
            }
            //UnityEngine.Debug.LogError("找不到野怪属性 "+ monsterId + " " + monsterLEvel);
            var l = new List<int>();
            for (int i = 0; i < 14; i++)
            {
                l.Add(0);
            }

            l[0] = 1000;
            l[1] = 100;
            l[2] = 100;
            return l;
        }

        public static int GetMonsterSkillLevel(int monsterId, int index)
        {
            if (monsterSkillLevels.TryGetValue(monsterId, out var list))
            {
                if (list.Count > index)
                {
                    return list[index];
                }
            }

            return 1;
        }

        public static void PreloadRpgSummonConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref summonConfigs);
        }
        
        public static void PreloadRpgObstacleConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref obstacleConfigs);
        }

        public static void PreloadRpgEffectConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref rpgEffectConfigs,"id");
        }

        public static void PreloadRpgHeroConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref heroConfigs,"id");
        }

        public static void PreloadRpgSkillConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref skillConfigs,"id");
        }

        public static void PreloadRpgConfig<T>(LuaTable table, ref Dictionary<int, T> dictionary,string mainKey = "id") where T:new()
        {
            if (dictionary != null)
            {
                return;
            }
            dictionary = new Dictionary<int, T>();
            var classType = typeof(T);
            var properties = classType.GetFields();
            for (int i = 1; i <= table.Length; i++)
            {
                var info = table.Get<int, LuaTable>(i);
                if (info != null)
                {
                    int id = getInt(info, mainKey);
                    T config = new T();
                    for (int j = 0; j < properties.Length; j++)
                    {
                        var name = properties[j].Name;
                        var type = properties[j].FieldType;
                        var value = GetValue(info, name, type);
                        properties[j].SetValue(config, value);
                    }
                    dictionary[id] = config;
                }
            }
        }
        public static void PreloadRpgConfig<T>(LuaTable table, ref Dictionary<string, T> dictionary, string mainKey = "id") where T : new()
        {
            if (dictionary != null)
            {
                return;
            }
            dictionary = new Dictionary<string, T>();
            var classType = typeof(T);
            var properties = classType.GetFields();
            for (int i = 1; i <= table.Length; i++)
            {
                
                var info = table.Get<int, LuaTable>(i);
                if (info != null)
                {
                    string id = GetValue<string>(info, mainKey);
                    T config = new T();
                    for (int j = 0; j < properties.Length; j++)
                    {
                        var name = properties[j].Name;
                        var type = properties[j].FieldType;
                        var value = GetValue(info, name, type);
                        properties[j].SetValue(config, value);
                    }
                    dictionary[id] = config;
                }
            }
        }

        public static object GetCsObjectFromLuaTable(string className, LuaTable classTable)
        {
            Type classType = Type.GetType(className);
            var obj = classType.Assembly.CreateInstance(className);
            var properties = classType.GetFields();
            for (int i = 0; i < properties.Length; i++)
            {
                var name = properties[i].Name;
                var type = properties[i].FieldType;
                var value = GetValue(classTable, name, type);
                properties[i].SetValue(obj,value);
            }
            return obj;
        }
        
        
        public static void PreloadRpgConfigWithSubKey<T>(LuaTable table, ref Dictionary<int,Dictionary<int, T>> dictionary,
            string mainKey = "id", string subKey = "id2") where T : new()
        {
            if (dictionary != null)
            {
                return;
            }
            dictionary = new Dictionary<int,Dictionary<int, T>>();
            var classType = typeof(T);
            var properties = classType.GetFields();
            for (int i = 1; i <= table.Length; i++)
            {
                var info = table.Get<int, LuaTable>(i);
                if (info != null)
                {
                    for (int j = 1; j <= info.Length; j++)
                    {
                        int id = 0;
                        var subInfo = info.Get<int, LuaTable>(j);
                        if (subInfo != null)
                        {
                            id = getInt(subInfo, mainKey);
                            int subId = getInt(subInfo, subKey);
                            T config = new T();
                            for (int k = 0; k < properties.Length; k++)
                            {
                                var name = properties[k].Name;
                                var type = properties[k].FieldType;
                                var value = GetValue(subInfo , name, type);
                                properties[k].SetValue(config, value);
                            }

                            Dictionary<int,T> subDic;
                            if (!dictionary.TryGetValue(id, out subDic))
                            {
                                subDic = new Dictionary<int, T>();
                                dictionary[id] = subDic;
                            }
                            subDic[subId] = config;
                        }
                    }
                }            }
        }

        public static void UpdatePveHeroAttributes(LuaTable table)
        {
            for (int i = 1; i <= table.Length; i++)
            {
                var info = table.Get<int, LuaTable>(i);
                if (info != null)
                {
                    int id = getInt(info, "id");
                    var attr = info.GetLuaTable("attribute");
                    var attributes = new List<int>();
                    for (int j = 1; j <= attr.Length; j++)
                    {
                        var value = attr.Get<int, int>(j);
                        attributes.Add(value);
                    }

                    var level = getInt(info, "level");
                    var star = getInt(info, "star");


                    var heroSkills = info.GetLuaTable("heroSkills");
                    var heroInitiative = heroSkills.GetLuaTable("skillInitiative");
                    var initiativeId = getInt(heroInitiative, "id");
                    var initiativeLevel = getInt(heroInitiative, "level");

                    List<Vector2Int> passives = new List<Vector2Int>();
                    var heroPassiveList = heroSkills.GetLuaTable("skillPassiveList");
                    for (int j = 1; j <= heroPassiveList.Length; j++)
                    {
                        var heroPassive = heroPassiveList.Get<int, LuaTable>(j);
                        var passiveId = getInt(heroPassive, "id");
                        var passiveLevel = getInt(heroPassive,"level");
                        if (passiveId > 0 && passiveLevel > 0)
                        {
                            passives.Add(new Vector2Int(passiveId,passiveLevel));
                        }
                    }

                    var pveHeroData = new PveHeroData
                    {
                        heroAttributes = attributes,
                        level = level,
                        star = star,
                        skillInitiative = initiativeId,
                        skillInitiativeLevel = initiativeLevel,
                        passiveSkillLevels = passives,
                    };
                    Debug.Log(string.Format("英雄属性更新 id={0} 等级={1}  星级={2}",id,level,star));
                    Debug.Log(string.Format("英雄主动技能 id={0} 等级={1}",initiativeId,initiativeLevel));
                    foreach(var item in passives)
                    {
                        Debug.Log(string.Format("英雄被动技能 id={0} 等级={1}",item.x,item.y));
                    }
                    heroAttributes[id] = pveHeroData;
                }
            }
        }

        public static void UpdatePveMonsterAttributes(LuaTable table)
        {
            monsterAttributes.Clear();
            monsterSkillLevels.Clear();
            for (int i = 1; i <= table.Length; i++)
            {
                var info = table.Get<int, LuaTable>(i);
                if (info != null)
                {
                    int id = getInt(info, "id");
                    int level = getInt(info, "level");
                    var attr = info.GetLuaTable("attribute");
                    Dictionary<int, List<int>> levels;
                    if (!monsterAttributes.TryGetValue(id, out levels))
                    {
                        levels = new Dictionary<int, List<int>>();
                        monsterAttributes.Add(id,levels);
                    }
                    var attributes = new List<int>();
                    for (int j = 1; j <= attr.Length; j++)
                    {
                        var value = attr.Get<int, int>(j);
                        attributes.Add(value);
                    }
                    levels[level] = attributes;

                    List<int> skillLevels;
                    var skillLevelsLua = info.GetLuaTable("skillLevels");
                    if (!monsterSkillLevels.TryGetValue(id, out skillLevels))
                    {
                        skillLevels = new List<int>();
                        monsterSkillLevels.Add(id,skillLevels);
                    }

                    for (int j = 1; j <= skillLevelsLua.Length; j++)
                    {
                        var value = skillLevelsLua.Get<int, int>(j);
                        skillLevels.Add(value);
                    }
                }
            }
        }

        public static void UpdatePveMonsterLevels(LuaTable table)
        {
            monsterLevels.Clear();
            for (int i = 1; i <= table.Length; i++)
            {
                var level = table.Get<int,int>(i);
                monsterLevels.Add(level);
            }
        }
        
        public static void PreloadRpgModelConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref rpgModelConfigs);
        }

        public static void PreloadRpgMonsterConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref rpgMonsterConfigs);
        }

        public static void PreloadExternalHeroConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref externalHeroConfig);
        }

        public static void PreloadRpgLevelMonsterConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref rpgLevelMonsterConfigs,"lv_id");
        }

        public static void PreloadRpgModelPlaceConfig(LuaTable table)
        {
            PreloadRpgConfigWithSubKey(table,ref rpgModelPlaceConfigs,"model_id","monster_place");
        }

        public static void PreloadRpgBulletConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref bulletConfigs,"id");
        }

        public static void PreloadRpgElementConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref elementConfigs,"id");
        }

        public static void PreloadRpgWeaponConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref weaponConfigs,"id");
        }

        public static void PreloadRpgSpecialObjectConfig(LuaTable table)
        {
            PreloadRpgConfig(table,ref specialObjectConfigs,"id");
        }

        public static void PreloadRpgResourceConfig(LuaTable table)
        {
            if (rpgResourceConfigs != null)
            {
                return;
            }
            rpgResourceConfigs = new Dictionary<int, RpgResourceConfig>();
            rpgKeyAndResourceConfigMap = new Dictionary<int, List<RpgResourceConfig>>();
            var classType = typeof(RpgResourceConfig);
            var properties = classType.GetFields();
            for (int i = 1; i <= table.Length; i++)
            {
                var info = table.Get<int, LuaTable>(i);
                if (info != null)
                {
                    int id = getInt(info, "id");
                    RpgResourceConfig config = new RpgResourceConfig();
                    for (int j = 0; j < properties.Length; j++)
                    {
                        var name = properties[j].Name;
                        var type = properties[j].FieldType;
                        var value = GetValue(info, name, type);
                        properties[j].SetValue(config, value);
                    }
                    rpgResourceConfigs[id] = config;
                    if (!rpgKeyAndResourceConfigMap.ContainsKey(config.type))
                    {
                        rpgKeyAndResourceConfigMap.Add(config.type,new List<RpgResourceConfig>());
                    }
                    rpgKeyAndResourceConfigMap[config.type].Add(config);
                }
            }
        }
        internal static void PreloadRpgNpcDialogContentConfig(LuaTable table)
        {
            PreloadRpgConfig<RpgNpcdialogcontent>(table, ref rpgNpcDialogContentConfig);
        }

        internal static void PreloadRpgNpcDialogConfig(LuaTable table)
        {
            PreloadRpgConfigWithSubKey<RpgNpcdialog>(table, ref rpgNpcDialogConfig,"id", "order");
        }

        internal static void PreloadRpgNpcEventConfig(LuaTable table)
        {
            PreloadRpgConfig<RpgNpcevent>(table, ref rpgNpcEventsConfig);
        }
        public static Dictionary<int, float> GetHeroBulletRatios()
        {
            var dic = new Dictionary<int, float>();
            foreach (var item in externalHeroConfig)
            {
                var  rpgNormalAttackSkillConfig = PveUtils.GetSkillConfig(item.Value.rpg_normal_attack_id);
                var modelConfig = PveUtils.GetRpgModelConfig(item.Value.rpg_model_id);
                var shootTurns = modelConfig.shoot_turns;
                var shootInterval = modelConfig.shoot_interval;
                var ammoCount = modelConfig.ammo_count;
                var reloadTime = modelConfig.reload_time;
                float singleAttackTime = rpgNormalAttackSkillConfig.attack_cast_time * shootTurns +
                                         rpgNormalAttackSkillConfig.storage_time + rpgNormalAttackSkillConfig.attack_recover_time;
                int attackRounds =
                    Mathf.CeilToInt(ammoCount / (float) rpgNormalAttackSkillConfig.bullets.Count / shootTurns);
                float averageInterval = 0;
                if (shootInterval != null && shootInterval.Count >= 2)
                {
                    averageInterval = (shootInterval[0] + shootInterval[1]) / 2f;
                }
                float totalTime = singleAttackTime * attackRounds + (attackRounds - 1) * averageInterval + reloadTime;
                var bulletDamageRatio = totalTime / ammoCount;
                dic.Add(item.Value.id,bulletDamageRatio);
            }
            return dic;
        }
       
        public static RpgResourceConfig GetRpgResourceConfig(int id)
        {
            if (!rpgResourceConfigs.TryGetValue(id, out var config))
            {
                Debug.LogError("资源配置找不到" + id);
            }
            return config;
        }

        public static List<RpgResourceConfig> GetRpgResourceConfigListByType(PveResourceManager.EPveResType resType)
        {
            if (rpgKeyAndResourceConfigMap.TryGetValue((int)resType,out var configList))
            {
                return configList;
            }

            return null;
        }

        public static RpgSummonConfig GetRpgSummonConfig(int id)
        {
            RpgSummonConfig config;
            if (!summonConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("找不到召唤物表" + id);
            }
            return config;
        }
        
        public static RpgObstacleConfig GetRpgObstacleConfig(int id)
        {
            RpgObstacleConfig config;
            if (!obstacleConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("找不到障碍物表" + id);
            }
            return config;
        }

        public static RpgEffectConfig GetRpgEffectConfig(int id)
        {
            RpgEffectConfig config;
            if (!rpgEffectConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("找不到特效表" + id);
            }
            return config;
        }

        public static RpgSpecialObjectConfig GetRpgSpecialObjectConfig(int id)
        {
            RpgSpecialObjectConfig config;
            if (!specialObjectConfigs.TryGetValue(id, out config))
            {
                //Debug.LogError("找不到特殊建筑表");
            }

            return config;
        }

        public static RpgLevelMonsterConfig GetRpgLevelMonsterConfig(int id)
        {
            RpgLevelMonsterConfig config;
            if (!rpgLevelMonsterConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("找不到关卡表 " + id);
                foreach (var item in rpgLevelMonsterConfigs.Values)
                {
                    config = item;
                    break;
                }
            }
            return config;
        }

        public static RpgModelPlaceConfig GetRpgModelPlaceConfig(int levelId,int positionId)
        {
            if (rpgModelPlaceConfigs.TryGetValue(levelId, out var dic) && dic.TryGetValue(positionId, out var config))
            {
                return config;
            }
            Debug.LogError("找不到怪物位置表");
            return null;
        }

        public static Dictionary<int,Vector3> GetRpgPlayerBirthPositions()
        {
            if (rpgModelPlaceConfigs.TryGetValue(1, out var dic))
            {
                Dictionary<int,Vector3> pos = new Dictionary<int,Vector3>();
                foreach (var item in dic)
                {
                    pos.Add(item.Value.monster_place,item.Value.place_pos);
                }
                return pos;
            }
            return null;
        }

        public static PveWeaponConfig GetWeaponConfig(int id)
        {
            PveWeaponConfig config;
            if (!weaponConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("武器配置找不到" + id);
            }
            return config;
        }

        public static ExternalHeroConfig GetExternalHeroConfig(int id)
        {
            ExternalHeroConfig config;
            if (!externalHeroConfig.TryGetValue(id, out config))
            {
                Debug.LogError("外部英雄表找不到" + id);
                config = new ExternalHeroConfig();
            }
            return config;
        }

        public static RpgMonsterConfig GetRpgMonsterConfig(int id)
        {
            RpgMonsterConfig config;
            if (!rpgMonsterConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("野怪配置找不到" + id);
                config = new RpgMonsterConfig();
            }
            return config;
        }

        public static RpgModelConfig GetRpgModelConfig(int id)
        {
            //根据id查找hero表中的模型id
            ExternalHeroConfig exConfig;
            externalHeroConfig.TryGetValue(id, out exConfig);
            int modelId = 0;
            if (exConfig != null)
            {
                modelId = exConfig.rpg_model_id;
            }
            else
            {
                //hero表中没有，rpg特有的，如狗的模型
                modelId = id;
            }
            RpgModelConfig config;
            if (!rpgModelConfigs.TryGetValue(modelId, out config))
            {
                Debug.LogError("英雄模型配置找不到" + id);
                config = new RpgModelConfig();
            }
            return config;
        }

        public static Dictionary<int, RpgModelPlaceConfig> GetRpgModelPlaceConfigs(int id)
        {
            Dictionary<int, RpgModelPlaceConfig> configs;
            if (!rpgModelPlaceConfigs.TryGetValue(id, out configs))
            {
                Debug.LogError("场景对应的位置配置找不到" + id);
                return null;
            }
            return configs;
        }

        public static PveHeroConfig GetHeroConfig(int id)
        {
            if (heroConfigs == null)
            {
                PreloadHeroConfig();
            }

            PveHeroConfig config;
            if (!heroConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("英雄配置找不到" + id);
                config =  new PveHeroConfig();
            }
            return config;
        }
        public static PveSkillConfig GetSkillConfig(int id)
        {
            /*if (skillConfigs == null)
            {
                PreloadSkillConfig();
            }*/

            PveSkillConfig config;
            if (!skillConfigs.TryGetValue(id, out config) && id != 0)
            {
                Debug.LogError("技能配置找不到" + id);
                config = new PveSkillConfig();
            }
            return config;
        }


        public static PveSkillBulletConfig GetSkillBulletConfig(int id)
        {
            /*if (bulletConfigs == null)
            {
                PreloadSkillBulletConfig();
            }*/

            PveSkillBulletConfig config;
            if (!bulletConfigs.TryGetValue(id, out config))
            {
                Debug.LogEditorError("子弹找不到" + id);
                config = new PveSkillBulletConfig();
            }
            return config;
        }

        public static PveSkillElementConfig GetSkillElementConfig(int id)
        {
            /*if (elementConfigs == null)
            {
                PreloadSkillElementConfig();
            }*/

            PveSkillElementConfig config;

            if (!elementConfigs.TryGetValue(id, out config))
            {
                Debug.LogError("元素找不到" + id);
                config = new PveSkillElementConfig();
            }
            return config;
        }

        private static void PreloadHeroConfig()
        {
            heroConfigs = new Dictionary<int, PveHeroConfig>();
            /*heroConfigs.Add(1,new PveHeroConfig//青兔
            {
                id = 1,
                modelId = 3009,
                pveAttackRange = 4f * globalRatio,
                pveNormalAttackId = 1001,
                pveHp = 800,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.qingtu1,
                rpgSkillId = (int)ESkillId.qingtu2,
                rpgSkillCost = 3,
                rpgAmmoCount = 8,
                rpgType = 2,
                moveSpeed = 5,
                attributeList = new List<float>{10,5,1000,100},
            });*/
            heroConfigs.Add(0,new PveHeroConfig//小富 近战
            {
                id = 0,
                modelId = 1000,
                pveAttackRange = 4f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 6f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.xiaofuMoving,
                //rpgPassiveSkillId = (int)ESkillId.gangtian1,
                rpgSkillId = (int)ESkillId.xiaofu2,
                rpgSkillCost = 3,
                ammoCount = 25,
                //rpgType = 2,
                moveSpeed = 4f,
                reloadTime = 2.1f,
                attributes = new List<float>{15,12,800,100,1,0.3f},
            });
            heroConfigs.Add(1,new PveHeroConfig//范迪塞尔
            {
                id = 1,
                modelId = 997,
                skillModelId = 900,
                pveAttackRange = 10f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 12f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.arthurMoving,
                //rpgPassiveSkill = (int)ESkillId.arthur2,
                rpgSkillId = (int)ESkillId.arthur3,
                rpgSkillCost = 4,
                ammoCount = 30,
                //rpgType = 2,
                moveSpeed = 4,//5,
                reloadTime = 1.633f,
                attributes = new List<float>{15,12,600,100,1,0.1f},
            });
            heroConfigs.Add(2,new PveHeroConfig//狙击枪
            {
                id = 2,
                modelId = 998,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 15f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.juji1,
                //rpgPassiveSkillId = (int)ESkillId.juji2,
                rpgSkillId = (int)ESkillId.qingtu2,
                rpgSkillCost = 4,
                ammoCount = 10,
                //rpgHp = 100,
                //rpgMp = 100,
                //rpgType = 2,
                moveSpeed = 4,//4.33f,
                reloadTime = 1.333f,
                attributes = new List<float>{40,8,400,100,1,0.1f},
            });
            heroConfigs.Add(3,new PveHeroConfig//狙击枪
            {
                id = 3,
                modelId = 998,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.juji1,
                //rpgPassiveSkillId = (int)ESkillId.juji2,
                rpgSkillId = (int)ESkillId.qingtu2,
                rpgSkillCost = 4,
                ammoCount = 10,
                //rpgHp = 100,
                //rpgMp = 100,
                //rpgType = 2,
                moveSpeed = 4,//4.33f,
                reloadTime = 1.333f,
                attributes = new List<float>{40,8,400,100,1,0.1f},
            });
            heroConfigs.Add(4,new PveHeroConfig//狙击枪
            {
                id = 4,
                modelId = 998,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.juji1,
                //rpgPassiveSkillId = (int)ESkillId.juji2,
                rpgSkillId = (int)ESkillId.qingtu2,
                rpgSkillCost = 4,
                ammoCount = 10,
                //rpgHp = 100,
                //rpgMp = 100,
                //rpgType = 2,
                moveSpeed = 4,//4.33f,
                reloadTime = 1.333f,
                attributes = new List<float>{40,8,400,100,1,0.1f},
            });
            heroConfigs.Add(5,new PveHeroConfig//冈田
            {
                id = 5,
                modelId = 996,
                pveAttackRange = 7f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 8f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.arthurMoving,
                //rpgPassiveSkill = (int)ESkillId.arthur2,
                rpgSkillId = (int)ESkillId.gangtian3,
                rpgSkillCost = 2,
                ammoCount = 10,
                //rpgType = 2,
                moveSpeed = 4,//5,
                reloadTime = 1.633f,
                attributes = new List<float>{15,8,600,100,1,0.1f},
            });
            heroConfigs.Add(6,new PveHeroConfig//唐纳德
            {
                id = 6,
                modelId = 994,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 8f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.donald1,
                rpgSkillId = (int)ESkillId.donald2,
                rpgSkillCost = 2,
                ammoCount = 10,
                //rpgType = 2,
                moveSpeed = 4,//5,
                reloadTime = 1.5633f,
                attributes = new List<float>{15,8,600,100,1,0.1f},
            });
            heroConfigs.Add(7,new PveHeroConfig//艾米
            {
                id = 7,
                modelId = 993,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 8f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.amy,
                rpgSkillId = (int)ESkillId.donald2,
                rpgSkillCost = 2,
                ammoCount = 7,
                //rpgType = 2,
                moveSpeed = 4,//5,
                reloadTime = 1.5633f,
                attributes = new List<float>{15,8,600,100,1,0.1f},
            });
            heroConfigs.Add(10,new PveHeroConfig//敌方
            {
                id = 10,
                modelId = 999,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 4f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.sandan1,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 2,
                reloadTime = 2.1f,
                moveSpeed = 4,
                attributes = new List<float>{25,5,200,100},
            });
            heroConfigs.Add(11,new PveHeroConfig//敌方
            {
                id = 11,
                modelId = 2004,
                pveAttackRange = 12f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 10f * globalRatio,
                rpgNormalAttackId = 1030,
                //rpgSkillId = 1100,
                rpgSkillCost = 5,
                //rpgAutoSkills = new List<int>{1101,1102,2003},
                ammoCount = 24,
                //rpgType = 0,
                moveSpeed = 5,
                attributes = new List<float>{6,5,100,100},
            });
            heroConfigs.Add(12,new PveHeroConfig//敌方
            {
                id = 12,
                modelId = 2004,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 12f * globalRatio,
                rpgNormalAttackId = 1030,
                //rpgSkillId = 1100,
                rpgSkillCost = 5,
                //rpgAutoSkills = new List<int>{1101,1102,2003},
                ammoCount = 36,
                //rpgType = 0,
                moveSpeed = 5,
                attributes = new List<float>{6,5,100,100},
            });
            heroConfigs.Add(13,new PveHeroConfig//敌方
            {
                id = 13,
                modelId = 2004,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 12f * globalRatio,
                rpgNormalAttackId = 1020,
                //rpgSkillId = 1100,
                rpgSkillCost = 5,
                //rpgAutoSkills = new List<int>{1101,1102,2003},
                ammoCount = 24,
                //rpgType = 0,
                moveSpeed = 5,
                attributes = new List<float>{6,5,100,100},
            });
            heroConfigs.Add(14,new PveHeroConfig//敌方
            {
                id = 14,
                //modelHeight = 2,
                modelId = 9999,
                pveAttackRange = 12f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 15f * globalRatio,
                rpgNormalAttackId = 1401,
                rpgSkillId = 1411,
                rpgSkillCost = 5,
                //rpgAutoSkills = new List<int>{1101,1102,2003},
                ammoCount = 20,
                //rpgType = 0,
                bossType = 1,
                moveSpeed = 5,
                attributes = new List<float>{15,5,1500,100},
            });
            heroConfigs.Add(15,new PveHeroConfig//敌方
            {
                id = 15,
                modelId = 1024,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 15f * globalRatio,
                rpgNormalAttackId = 1024,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 2,
                moveSpeed = 5,
                attributes = new List<float>{6,5,100,100},
            });
            heroConfigs.Add(16,new PveHeroConfig//敌方霰弹枪
            {
                id = 16,
                modelId = 999,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.sandan1,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 2,
                moveSpeed = 4,
                attributes = new List<float>{25,5,100,100},
            });
            heroConfigs.Add(160,new PveHeroConfig//敌方霰弹枪（挂机）
            {
                id = 160,
                modelId = 999,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.sandan1,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 2,
                moveSpeed = 4,
                attributes = new List<float>{6,5,20,100},
            });
            heroConfigs.Add(17,new PveHeroConfig//敌方狙击枪
            {
                id = 17,
                modelId = 998,
                pveAttackRange = 8f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 15f * globalRatio,
                rpgNormalAttackId = (int)ESkillId.juji1,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 10,
                //rpgHp = 100,
                //rpgMp = 100,
                //rpgType = 2,
                moveSpeed = 4.33f,
                attributes = new List<float>{30,5,100,100},
            });
            heroConfigs.Add(18,new PveHeroConfig//敌方范迪塞尔
            {
                id = 18,
                modelId = 997,
                pveAttackRange = 8f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 20f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.arthurMoving,
               ammoCount = 10,
               //rpgType = 2,
                moveSpeed = 5,
                reloadTime = 2.1f,
                bossType = 1,
                attributes = new List<float>{10,5,500,100},
            });
            heroConfigs.Add(19,new PveHeroConfig//敌方斯沃特
            {
                id = 19,
                modelId = 995,
                pveAttackRange = 8f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 10f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.swat1,
                ammoCount = 5,
                //rpgType = 2,
                moveSpeed = 4,
                reloadTime = 1.6f,
                attributes = new List<float>{10,5,200,100},
            });
            heroConfigs.Add(20,new PveHeroConfig//敌方sm
            {
                id = 20,
                modelId = 992,
                pveAttackRange = 8f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 8f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.sm1,
                ammoCount = 12,
                //rpgType = 2,
                moveSpeed = 4,
                reloadTime = 1.567f,
                attributes = new List<float>{10,5,200,100},
            });
            heroConfigs.Add(21,new PveHeroConfig//敌方riot
            {
                id = 21,
                modelId = 991,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 5f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.riot1,
                ammoCount = 9,
                //rpgType = 2,
                moveSpeed = 4,
                reloadTime = 1.467f,
                attributes = new List<float>{10,5,400,100},
            });
            heroConfigs.Add(22,new PveHeroConfig//敌方bo
            {
                id = 22,
                modelId = 990,
                pveAttackRange = 10f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 10f * globalRatio,
                rpgNormalAttackId =  (int)ESkillId.bo1,
                ammoCount = 1,
                //rpgType = 2,
                moveSpeed = 4,
                reloadTime = 0.9f,
                attributes = new List<float>{10,5,200,100},
            });
            heroConfigs.Add(100,new PveHeroConfig//敌方小飞机
            {
                id = 100,
                modelId = 10000,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 3f * globalRatio,
                rpgNormalAttackId = 1028,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 0,
                moveSpeed = 5,
                attributes = new List<float>{6,5,50,100},
            });
            heroConfigs.Add(101,new PveHeroConfig//敌方小飞机
            {
                id = 101,
                modelId = 10000,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 6f * globalRatio,
                rpgNormalAttackId = 1028,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 0,
                moveSpeed = 5,
                attributes = new List<float>{6,5,50,100},
            });
            heroConfigs.Add(102,new PveHeroConfig//敌方大飞机
            {
                id = 102,
                modelId = 10001,
                pveAttackRange = 6f * globalRatio,
                //pveNormalAttackId = 1001,
                //pveHp = 800,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = 1027,
                rpgSkillId = 1412,
                //rpgNormalAttackSubId = 1022,
                ammoCount = 5,
                //rpgType = 0,
                moveSpeed = 5,
                attributes = new List<float>{6,5,200,100},
            });
            /*heroConfigs.Add(10,new PveHeroConfig//敌方前排散弹
            {
                id = 10,
                modelId = 2,
                pveAttackRange = 6f * globalRatio,
                pveNormalAttackId = 1002,
                pveHp = 100,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = 1000,
                //rpgSkillId = 1100,
                rpgHp = 100,
                rpgMp = 100,
            });

            heroConfigs.Add(11,new PveHeroConfig//敌方后排手雷
            {
                id = 11,
                modelId = 2,
                pveAttackRange = 6f * globalRatio,
                pveNormalAttackId = 1002,
                pveHp = 100,
                rpgAttackRange = 12f * globalRatio,
                rpgNormalAttackId = 1000,
                rpgSkillId = 1300,
                rpgHp = 100,
                rpgMp = 100,
                searchSort = 2,
            });
            heroConfigs.Add(12,new PveHeroConfig//敌方后排火箭
            {
                id = 12,
                modelId = 2,
                pveAttackRange = 2.5f * globalRatio,
                pveNormalAttackId = 1002,
                pveHp = 100,
                rpgAttackRange = 12f * globalRatio,
                rpgNormalAttackId = 1000,
                //rpgSkillId = 1600,
                //rpgAutoSkills = new List<int>{1103},
                rpgHp = 100,
                rpgMp = 100,
                searchSort = 2,
            });
            heroConfigs.Add(13,new PveHeroConfig//敌方前排刺客
            {
                id = 13,
                modelId = 2,
                pveAttackRange = 2.5f * globalRatio,
                pveNormalAttackId = 1002,
                pveHp = 100,
                rpgAttackRange = 9f * globalRatio,
                rpgNormalAttackId = 1000,
                //rpgSkillId = 1200,
                //rpgAutoSkills = new List<int>{1103},
                rpgHp = 100,
                rpgMp = 100,
            });*/
        }

        public static int GetHeroIdByIndex(int index)
        {
            if (deckHeroes.Count > index)
            {
                return deckHeroes[index];
            }
            return 4;
        }

        public static List<int> deckHeroes = new List<int>();
        public static Dictionary<int, int> deckHeroInfo = new Dictionary<int, int>();
        public static List<int> deckCards = new List<int>();
        
        private static Dictionary<int, int> cardInfo = new Dictionary<int, int>();

        public static List<int> GetSelfHeroList()
        {
            /*var list = new List<int>();
            list.AddRange(deckHeroes);
            if (true) //检查是否需要额外添加英雄
            {
                list.Add(41008);
            }

            return list;*/
            return deckHeroes;
        }

        public static int GetCostByCardId(int id)
        {
            if (cardInfo.TryGetValue(id, out var cost))
            {
                return cost;
            }
            return 0;
        }

        public static void UpdateCardInfo(LuaTable table)
        {
            cardInfo.Clear();
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int,LuaTable>(i);
                int id = getInt(item, "id");
                int cost = getInt(item, "cost");
                cardInfo[id] = cost;
            }
        }

        public static void UpdatePveHeroes(LuaTable table)
        {
            deckHeroes.Clear();
            for (int i = 1; i <= table.Length; i++)
            {
                var heroId = table.Get<int, int>(i);
                if (heroId > 0)
                {
                    deckHeroes.Add(heroId);
                }
            }
        }

        public static void UpdatePveCards(LuaTable table)
        {
            deckCards.Clear();
            for (int i = 1; i <= table.Length; i++)
            {
                var cardId = table.Get<int, int>(i);
                if (cardId > 0)
                {
                    deckCards.Add(cardId);
                }
            }
        }

        public static void PreLoadDeckHeroInfo(LuaTable table)
        {
            deckHeroes.Clear();
            deckHeroInfo.Clear();
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int, LuaTable>(i);
                int heroId = item.Get<string, int>("heroId");
                int sort = item.Get<string, int>("sort");
                sort--;
                if (!deckHeroes.Contains(heroId))
                {
                    deckHeroes.Add(heroId);
                }
                deckHeroInfo[heroId] = sort;
            }
        }

        public static void PreloadLangConfigs(LuaTable table)
        {
            for (int i = 1; i <= table.Length; i++)
            {
                var item = table.Get<int, LuaTable>(i);
                var key = item.Get<string, string>("key");
                var value = item.Get<string, string>("value");
                langConfigs[key] = value;
            }
        }

        public static string GetLangText(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return string.Empty;
            }
            if (langConfigs.TryGetValue(key, out var value))
            {
                if (string.IsNullOrEmpty(value))
                {
                    Debug.LogError(key+"文本找不到");
                    return key;
                }
                return value;
            }

            var content = ResidentHandler.Inst.GetFunction("pveManager.GetLangText").Call(key)[0].ToString();
            langConfigs[key] = content;
            return content;
        }

        public static Vector3 GetCameraGroundPosition(Camera camera = null)
        {
            Transform transform;
            if (camera)
            {
                transform = camera.transform;
            }
            else
            {
                transform = WorldCameraManager.cameraController.CameraTransform;
            }
            
            Vector3 dir = transform.forward;
            var position = transform.position;
            float height = position.y;
            Vector3 offset = dir * height / dir.y;
            return position - offset;
        }

        public static Vector3 GetCameraGroundPosition(Transform transform)
        {
            Vector3 dir = transform.forward;
            var position = transform.position;
            float height = position.y;
            Vector3 offset = dir * height / dir.y;
            return position - offset;
        }


        public static void MoveCameraTo(Vector3 target,float time,Action onOver)
        {
            var cameraController = WorldCameraManager.cameraController;
            cameraController.CameraTransform.DOKill();
            var position = cameraController.CameraTransform.position;
            var currentCenter = GetCameraGroundPosition();
            Vector3 offset = target - currentCenter;
            //cameraController.Lock = true;

            cameraController.CameraTransform.DOMove(position + offset, time).SetEase(Ease.Linear).OnComplete(() =>
            {
                //cameraController.Lock = false;
                onOver?.Invoke();
            });
        }

        public static void ZoomCameraTo(float zoom,float time,Action onOver)
        {
            var cameraController = WorldCameraManager.cameraController;
            cameraController.CameraTransform.DOKill();
            var position = cameraController.CameraTransform.position;
            var currentCenter = GetCameraGroundPosition();
            zoom = Mathf.Clamp(zoom, cameraController.ZoomDistanceMin, cameraController.ZoomDistanceMax);
            Vector3 offset = currentCenter - cameraController.CameraTransform.forward * zoom;
            //cameraController.Lock = true;

            cameraController.CameraTransform.DOMove(offset, time).SetEase(Ease.Linear).OnComplete(() =>
            {
                //cameraController.Lock = false;
                onOver?.Invoke();
            });
        }

        public static float GetAngle(Vector3 from, Vector3 to)
        {
            float angle;
            Vector3 cross = Vector3.Cross(from, to);
            angle = Vector3.Angle(from, to);
            return cross.y > 0 ? angle : -angle;
        }

        
        public static float GetAngleServer(Vector3 from, Vector3 to)
        {
            float angle;
            Vector3 cross = Vector3.Cross(from, to);
            angle = Vector3.Angle(from, to);
            return cross.y < 0 ? angle : 360-angle;
        }
        
        public static BehaviorData GetMortalBehaviorData()
        {
            var data = new BehaviorData();
            data.rootId = 1;
            data.composites = new Dictionary<int, int[]>();
            data.decorators = new Dictionary<int, int>();
            data.sharedVariables = new Dictionary<string, object>();
            data.composites.Add(1,new []{2,3});
            data.composites.Add(2,new []{4,5});
            data.composites.Add(3,new []{6});
            data.tasks = new[]
            {
                new BehaviorData.TaskData
                {
                    id = 1,
                    taskType = 2,
                    className = "Selector"
                },
                new BehaviorData.TaskData
                {
                    id = 2,
                    taskType = 2,
                    className = "Sequence"
                },
                new BehaviorData.TaskData
                {
                    id = 3,
                    taskType = 2,
                    className = "Sequence"
                },
                new BehaviorData.TaskData
                {
                    id = 4,
                    taskType = 1,
                    className = "HasBattleInSight"
                },
                new BehaviorData.TaskData
                {
                    id = 5,
                    taskType = 1,
                    className = "Escape"
                },
                new BehaviorData.TaskData
                {
                    id = 6,
                    taskType = 1,
                    className = "MortalAction"
                },
            };
            return data;
        }

        public static BehaviorData GetVehicleBehaviorData()
        {
            var data = new BehaviorData();
            data.rootId = 1;
            data.composites = new Dictionary<int, int[]>();
            data.decorators = new Dictionary<int, int>();
            data.sharedVariables = new Dictionary<string, object>();
            data.composites.Add(1,new []{2,3});
            data.composites.Add(2,new []{4,5});
            data.composites.Add(3,new []{6});
            data.tasks = new[]
            {
                new BehaviorData.TaskData
                {
                    id = 1,
                    taskType = 2,
                    className = "Selector"
                },
                new BehaviorData.TaskData
                {
                    id = 2,
                    taskType = 2,
                    className = "Sequence"
                },
                new BehaviorData.TaskData
                {
                    id = 3,
                    taskType = 2,
                    className = "Sequence"
                },
                new BehaviorData.TaskData
                {
                    id = 4,
                    taskType = 1,
                    className = "HasObstacleFront"
                },
                new BehaviorData.TaskData
                {
                    id = 5,
                    taskType = 1,
                    className = "Wait"
                },
                new BehaviorData.TaskData
                {
                    id = 6,
                    taskType = 1,
                    className = "VehicleAction"
                },
            };
            return data;
        }


        public static BehaviorData GetTestBehaviorData()
        {
            var data = new BehaviorData();
            data.rootId = 1;
            data.composites = new Dictionary<int, int[]>();
            data.decorators = new Dictionary<int, int>();
            data.sharedVariables = new Dictionary<string, object>();

            data.composites.Add(1,new []{12,8,9,2,3});
            data.composites.Add(2,new []{4,5});
            data.composites.Add(3,new []{6,7});
            data.composites.Add(9,new []{10,11});
            /*data.decorators = new Dictionary<int, int>
            {
                [4] = 8,
                [6] = 9,
            };*/

            data.tasks = new[]
            {
                new BehaviorData.TaskData
                {
                    id = 1,
                    taskType = 2,
                    className = "Selector"
                },
                new BehaviorData.TaskData
                {
                    id = 2,
                    taskType = 2,
                    className = "Sequence"
                },
                new BehaviorData.TaskData
                {
                    id = 3,
                    taskType = 2,
                    className = "Sequence"
                },
                /*new BehaviorData.TaskData
                {
                    id = 4,
                    taskType = 2,
                    className = "Inverter"
                },*/
                new BehaviorData.TaskData
                {
                    id = 4,
                    taskType = 1,
                    className = "IsHaveLockTarget"
                },
                new BehaviorData.TaskData
                {
                    id = 5,
                    taskType = 1,
                    className = "SearchTarget"
                },
                /*new BehaviorData.TaskData
                {
                    id = 6,
                    taskType = 2,
                    className = "Inverter"
                },*/
                new BehaviorData.TaskData
                {
                    id = 6,
                    taskType = 1,
                    className = "IsAttackInRange"
                },
                new BehaviorData.TaskData
                {
                    id = 7,
                    taskType = 1,
                    className = "MoveToAttack"
                },
                new BehaviorData.TaskData
                {
                    id = 8,
                    taskType = 1,
                    className = "IsObeyingOrder"
                },
                new BehaviorData.TaskData
                {
                    id = 9,
                    taskType = 2,
                    className = "Sequence"
                },
                new BehaviorData.TaskData
                {
                    id = 10,
                    taskType = 1,
                    className = "CanAutoUseSkill"
                },
                new BehaviorData.TaskData
                {
                    id = 11,
                    taskType = 1,
                    className = "UseSkill"
                },
                new BehaviorData.TaskData
                {
                    id = 12,
                    taskType = 1,
                    className = "IsInitiative"
                },
            };
            return data;
        }


        public static Vector2 GetIntersection(Vector2 lineAStart,Vector2 lineAEnd, Vector2 lineBStart,Vector2 lineBEnd,bool withoutSide = false)
        {
            float x1 = lineAStart.x, y1 = lineAStart.y;
            float x2 = lineAEnd.x, y2 = lineAEnd.y;

            float x3 = lineBStart.x, y3 = lineBStart.y;
            float x4 = lineBEnd.x, y4 = lineBEnd.y;

            //equations of the form x=c (two vertical lines)
            if (x1 == x2 && x3 == x4 && x1 == x3)
            {
                return Vector2.zero;
            }

            //equations of the form y=c (two horizontal lines)
            if (y1 == y2 && y3 == y4 && y1 == y3)
            {
                return Vector2.zero;
            }

            //equations of the form x=c (two vertical lines)
            if (x1 == x2 && x3 == x4)
            {
                return Vector2.zero;
            }

            //equations of the form y=c (two horizontal lines)
            if (y1 == y2 && y3 == y4)
            {
                return Vector2.zero;
            }
            float x, y;

            if (x1 == x2)
            {
                float m2 = (y4 - y3) / (x4 - x3);
                float c2 = -m2 * x3 + y3;

                x = x1;
                y = c2 + m2 * x1;
            }
            else if (x3 == x4)
            {
                float m1 = (y2 - y1) / (x2 - x1);
                float c1 = -m1 * x1 + y1;

                x = x3;
                y = c1 + m1 * x3;
            }
            else
            {
                //compute slope of line 1 (m1) and c2
                float m1 = (y2 - y1) / (x2 - x1);
                float c1 = -m1 * x1 + y1;

                //compute slope of line 2 (m2) and c2
                float m2 = (y4 - y3) / (x4 - x3);
                float c2 = -m2 * x3 + y3;

                //solving equations (3) & (4) => x = (c1-c2)/(m2-m1)
                //plugging x value in equation (4) => y = c2 + m2 * x
                x = (c1 - c2) / (m2 - m1);
                y = c2 + m2 * x;

                //          if (!(-m1 * x + y == c1
                //              && -m2 * x + y == c2))
                //          {
                //              return Vector3.zero;
                //          }
            }

            if (IsInsideLine(lineAStart,lineAEnd, x, y) &&
                IsInsideLine(lineBStart,lineBEnd, x, y))
            {
                return new Vector2(x,y);
            }

            //return default null (no intersection)
            return Vector2.zero;
        }


        private static bool IsInsideLine(Vector2 start, Vector2 end, float x, float y)
        {
            return ((x >= start.x && x <= end.x)
                || (x >= end.x && x <= start.x))
                && ((y >= start.y && y <= end.y)
                    || (y >= end.y && y <= start.y));
        }

        private static List<Vector3> selfRPGPosition = new List<Vector3>
        {
            2.5f * globalRatio * new Vector3(-2, 0, 0),
            2.5f * globalRatio * new Vector3(-3f, 0, -2),
            2.5f * globalRatio * new Vector3(-3f, 0, 2),
            2.5f * globalRatio * new Vector3(-3.2f, 0, 0),
        };

        private static List<Vector3> enemyRPGPosition = new List<Vector3>
        {
            2.5f * globalRatio * new Vector3(2, 0, 0),
            2.5f * globalRatio * new Vector3(3f, 0, -2),
            2.5f * globalRatio * new Vector3(3f, 0, 2),
            2.5f * globalRatio * new Vector3(4, 0, 1),
            2.5f * globalRatio * new Vector3(4, 0, -1),
        };

        private static List<Vector3> selfPvePosOffset = new List<Vector3>
        {
            new Vector3(0,0,0) * globalRatio,
            new Vector3(1.3f,0,-2) * globalRatio,
            new Vector3(-1.3f,0,-2f) * globalRatio,
            new Vector3(2f,0,-3f) * globalRatio,
            new Vector3(-2f,0,-3f) * globalRatio,
            new Vector3(1f,0,-3f) * globalRatio,
            new Vector3(-1f,0,-3f) * globalRatio,
            new Vector3(2.5f,0,-3f) * globalRatio,
            new Vector3(-2.5f,0,-3f) * globalRatio,
        };

        /*private static List<Vector3> enemyPveBirthOffset = new List<Vector3>
        {
            0.6f* globalRatio * new Vector3(0,0,0) + new Vector3(0,0,10),
            0.6f* globalRatio * new Vector3(-6f,0,3.6f) + new Vector3(0,0,10),
            0.6f* globalRatio * new Vector3(8f,0,1.4f) + new Vector3(0,0,10),
            0.6f* globalRatio * new Vector3(5.1f,0,3.5f) + new Vector3(0,0,10),
            0.6f* globalRatio * new Vector3(-3.9f,0,5.5f) + new Vector3(0,0,10),

            0.6f* globalRatio * new Vector3(0,0,0) + new Vector3(0,0,35),
            0.6f* globalRatio * new Vector3(-6f,0,3.6f) + new Vector3(0,0,35),
            0.6f* globalRatio * new Vector3(8f,0,1.4f) + new Vector3(0,0,35),
            0.6f* globalRatio * new Vector3(5.1f,0,3.5f) + new Vector3(0,0,35),
            0.6f* globalRatio * new Vector3(-3.9f,0,5.5f) + new Vector3(0,0,35),
        };*/

        private static List<Vector3> enemyPveBirthOffset = new List<Vector3>
        {
            globalRatio * new Vector3(5,0,1) + new Vector3(0,0,15),
            globalRatio * new Vector3(4f,0,3f) + new Vector3(0,0,15),
            globalRatio * new Vector3(3.5f,0,5f) + new Vector3(0,0,15),
            globalRatio * new Vector3(-7f,0,1f) + new Vector3(0,0,15),
            globalRatio * new Vector3(-8f,0,3f) + new Vector3(0,0,15),
            globalRatio * new Vector3(-9f,0,5f) + new Vector3(0,0,15),
        };

        private static List<Vector3> enemyPveBattleOffset = new List<Vector3>
        {
            globalRatio * 1.2f * new Vector3(0,0,0),
            globalRatio * 1.2f * new Vector3(-2.3f,0,0.5f),
            globalRatio * 1.2f * new Vector3(3f,0,0.8f),
            globalRatio * 1.2f * new Vector3(0,0,0),
            globalRatio * 1.2f * new Vector3(-2.3f,0,0.5f),
            globalRatio * 1.2f * new Vector3(3f,0,0.8f),
        };

        private static List<int> rpgLevelList = new List<int> {0, 1, 2, 3, 4};

        private static Dictionary<int,Vector3> obstacleSizes = new Dictionary<int,Vector3>
        {
            [100] = globalRatio * new Vector3(0.9f,0,2.5f),
            [101] = globalRatio * new Vector3(1,0,0.3f),
            [102] = globalRatio * new Vector3(1,0,0.3f),
        };


        private static List<Vector3> obstaclePositions = new List<Vector3>
        {
            new Vector3(0,0,0),
            new Vector3(-4f,0,2),
            new Vector3(-4f,0,-2),
        };

        private static List<Vector3> obstacleHidePositions = new List<Vector3>
        {
            new Vector3(-1f,0,0),
            new Vector3(-4.7f,0,2),
            new Vector3(-4.7f,0,-2),
        };

        public static Vector3 GetObstacleSize(int index)
        {
            if (obstacleSizes.TryGetValue(index,out var size))
            {
                return size;
            }
            return new Vector3(1,1,1);
        }

        public static Vector3 GetObstacleHidePosition(int index)
        {
            if (index < obstacleHidePositions.Count)
            {
                return obstacleHidePositions[index];
            }
            return Vector3.zero;
        }

        public static Vector3 GetObstaclePosition(int index)
        {
            if (index < obstaclePositions.Count)
            {
                return obstaclePositions[index];
            }
            return Vector3.zero;
        }

        public static Vector3 GetSelfRpgPosition(int index)
        {
            return selfRPGPosition[index];// + new Vector3(UnityEngine.Random.Range(-2f,2f),0,0);
        }

        public static Vector3 GetEnemyRpgPosition(int index)
        {
            return enemyRPGPosition[index];
        }

        public static Vector3 GetSelfPvePosOffset(int index)
        {
            return selfPvePosOffset[index];
        }

        public static Vector3 GetEnemyPvePosOffset(int index)
        {
            if (index >= enemyPveBirthOffset.Count)
            {
                return enemyPveBirthOffset[0];
            }
            return enemyPveBirthOffset[index];
        }

        public static int GetEnemyPveCount()
        {
            return enemyPveBirthOffset.Count;
        }

        public static int GetRpgLevelId(int index)
        {
            return rpgLevelList[index % rpgLevelList.Count];
        }

        public static Vector3 GetEnemyBattlePosOffset(int index)
        {
            if (index >= enemyPveBattleOffset.Count)
            {
                return enemyPveBattleOffset[0];
            }
            return enemyPveBattleOffset[index];
        }

        public static TbsHeroConfig GetTbsHeroConfig(int id)
        {
            if (tbsHeroConfigs == null)
            {
                PreloadTbsHeroConfigs();
            }

            if (tbsHeroConfigs.TryGetValue(id, out var table))
            {
                return table;
            }

            return default;
        }

        public static Dictionary<int, TbsSkillConfig> GetAllTbsSkillConfig()
        {
            if (tbsSkillConfigs == null)
            {
                PreloadTbsSkillConfigs();
            }
            return tbsSkillConfigs;
        }

        public static TbsSkillConfig GetTbsSkillConfig(int id)
        {
            if (tbsSkillConfigs == null)
            {
                PreloadTbsSkillConfigs();
            }

            if (tbsSkillConfigs.TryGetValue(id, out var table))
            {
                return table;
            }

            return default;
        }

        public static TbsSkillPlayerConfig GetTbsSkillPlayerConfig(int id)
        {
            if (tbsSkillPlayerConfigs != null && tbsSkillPlayerConfigs.TryGetValue(id,out var table))
            {
                return table;
            }
            return default;
        }


        public static TbsSkillElementConfig GetTbsSkillElementConfig(int id)
        {
            if (tbsElementConfigs == null)
            {
                PreloadTbsSkillElementConfigs();
            }

            if (tbsElementConfigs.TryGetValue(id, out var table))
            {
                return table;
            }

            return default;
        }

        private static void PreloadTbsHeroConfigs()
        {
            tbsHeroConfigs = new Dictionary<int, TbsHeroConfig>();
            //我方
            tbsHeroConfigs.Add(0,new TbsHeroConfig//三连击角色
            {
                id = 0,
                modelId = 2004,
                attackId = 200401,
                skillId = 200402,
                property = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(1,new TbsHeroConfig//纵列角色
            {
                id = 1,
                modelId = 2004,
                attackId = 200401,
                skillId = 200402,
                property = 2,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(2,new TbsHeroConfig//后排角色
            {
                id = 2,
                modelId = 2001,
                attackId = 200101,
                skillId = 200102,
                property = 3,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(3,new TbsHeroConfig//治疗角色
            {
                id = 3,
                modelId = 2003,
                attackId = 200301,
                skillId = 200302,
                property = 1,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(4,new TbsHeroConfig//群体攻击角色
            {
                id = 4,
                modelId = 2002,
                attackId = 200201,
                skillId = 200202,
                property = 2,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(5,new TbsHeroConfig//刺客角色
            {
                id = 5,
                modelId = 2003,
                attackId = 200301,
                skillId = 200302,
                property = 3,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(6,new TbsHeroConfig//夸父
            {
                id = 6,
                modelId = 2003,
                attackId = 200301,
                skillId = 200302,
                property = 3,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            //敌方
            tbsHeroConfigs.Add(10,new TbsHeroConfig
            {
                id = 10,
                modelId = 2004,
                attackId = 200401,
                skillId = 200402,
                //passiveSkills = new List<int>{2003},
                critChance = 7000,
                critTimes = 20000,
                property = 1,
            });
            tbsHeroConfigs.Add(11,new TbsHeroConfig
            {
                id = 11,
                modelId = 2004,
                attackId = 200401,
                skillId = 200402,
                //passiveSkills = new List<int>{2003},
                critChance = 7000,
                critTimes = 20000,
                property = 2,
            });
            tbsHeroConfigs.Add(12,new TbsHeroConfig
            {
                id = 12,
                modelId = 2004,
                attackId = 200401,
                skillId = 200402,
                //passiveSkills = new List<int>{2003},
                critChance = 7000,
                critTimes = 20000,
                property = 3,
            });
            tbsHeroConfigs.Add(13,new TbsHeroConfig
            {
                id = 13,
                modelId = 2003,
                attackId = 200301,
                skillId = 200302,
                property = 1,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(14,new TbsHeroConfig
            {
                id = 14,
                modelId = 2003,
                attackId = 200301,
                skillId = 200302,
                property = 2,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
            tbsHeroConfigs.Add(15,new TbsHeroConfig
            {
                id = 15,
                modelId = 2003,
                attackId = 200301,
                skillId = 200302,
                property = 3,
                type = 1,
                critChance = 7000,
                critTimes = 20000,
            });
        }


        private static void PreloadTbsSkillConfigs()
        {
            tbsSkillConfigs = new Dictionary<int, TbsSkillConfig>();
            tbsSkillConfigs.Add(1000,new TbsSkillConfig//普攻近战敌方
            {
                id = 1000,
                attackRange = 0.3f,
                storageFrame = 1,
                castFrame = 35,
                recoverFrame = 1,
                moveType = 1,
                targetNum = 1,
                focus = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,100000,0),
                    new Vector3(25,100003,0),
                },
            });
            tbsSkillConfigs.Add(1001,new TbsSkillConfig//普攻远程我方
            {
                id = 1001,
                attackRange = 0.3f,
                storageFrame = 1,
                castFrame = 35,
                recoverFrame = 1,
                moveType = 2,
                targetNum = 1,
                focus = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,100001,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800001,0),
                },
            });
            tbsSkillConfigs.Add(1002,new TbsSkillConfig//普攻远程敌方
            {
                id = 1002,
                attackRange = 0.3f,
                storageFrame = 1,
                castFrame = 35,
                recoverFrame = 1,
                moveType = 2,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,100000,0),
                },
            });
            tbsSkillConfigs.Add(1003,new TbsSkillConfig//普攻远程我方
            {
                id = 1003,
                attackRange = 0.3f,
                storageFrame = 1,
                castFrame = 35,
                recoverFrame = 1,
                moveType = 2,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,100001,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(100801,new TbsSkillConfig//普攻远程1008
            {
                id = 100801,
                attackRange = 0.6f,
                storageFrame = 0,
                castFrame = 67,//127 + 66,
                recoverFrame = 0,
                moveType = 1,
                targetNum = 1,
                moveToSpeed = 1,
                moveToDelayFrame = 8,
                moveToFrame = 10,
                moveBackSpeed = 1,
                moveBackFrame = 53,
                moveBackDelayFrame = 8,
                moveBackStayFrame = 25,
                actionNameBefore = "Skill_",
                //cameraFrame = 99,
                castEvent = new List<Vector3>
                {
                    new Vector3(42,100001,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(200101,new TbsSkillConfig//普攻远程2001
            {
                id = 200101,
                attackRange = 2f,
                storageFrame = 0,
                castFrame = 51,
                recoverFrame = 0,
                moveType = 0,
                targetNum = 1,
                cameraFrame = 99,
                castEvent = new List<Vector3>
                {
                    new Vector3(20,100001,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(200102,new TbsSkillConfig//技能远程2001
            {
                id = 200102,
                attackRange = 2f,
                storageFrame = 0,
                castFrame = 87,
                recoverFrame = 0,
                moveType = 0,
                targetNum = 1,
                actionName = "Skill",
                cameraFrame = 90,
                castEvent = new List<Vector3>
                {
                    new Vector3(65,200001,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(200201,new TbsSkillConfig//近战普通2002
            {
                id = 200201,
                attackRange = 1f,
                storageFrame = 0,
                castFrame = 55,
                recoverFrame = 0,
                moveType = 1,
                targetNum = 1,
                castEvent = new List<Vector3>()
                {
                    new Vector3(26,100001,0),
                }
            });
            tbsSkillConfigs.Add(200202,new TbsSkillConfig//远程技能2002
            {
                id = 200202,
                attackRange = 2f,
                storageFrame = 0,
                castFrame = 94,
                recoverFrame = 0,
                moveType = 0,
                targetNum = 5,
                targetSort = 0,
                actionName = "Skill",
                cameraFrame = 92,
                castEvent = new List<Vector3>()
                {
                    new Vector3(85,200001,0),
                    new Vector3(94,800003,0),//电元素
                }

            });
            tbsSkillConfigs.Add(200401,new TbsSkillConfig//普攻近战2004
            {
                id = 200401,
                attackRange = 1f,
                moveToSpeed = 2,
                moveToDelayFrame = (int)(13 * 1.25f),
                moveToFrame = (int)(25 * 1.25f),
                moveBackSpeed = 2,
                moveBackFrame = (int)(30 * 1.25f),
                storageFrame = 0,
                moveBackDelayFrame = (int)(3 * 1.25f),
                moveBackStayFrame = (int)(15 * 1.25f),
                castFrame = (int)(13 * 1.25f),
                recoverFrame = 0,
                moveType = 1,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3((int)(7 * 1.25f),100001,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(200402,new TbsSkillConfig//技能近战2004
            {
                id = 200402,
                attackRange = 2f,
                storageFrame = 0,
                castFrame = 60,
                recoverFrame = 0,
                moveType = 0,
                targetNum = 1,
                cameraFrame = 65,
                castEvent = new List<Vector3>
                {
                    new Vector3(35,200001,0),
                    new Vector3(35,800004,0),//火元素
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(200301,new TbsSkillConfig//普攻远程2003
            {
                id = 200301,
                attackRange = 2f,
                storageFrame = 0,
                castFrame = 51,
                recoverFrame = 0,
                moveType = 0,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(26,100001,0),
                },
            });
            tbsSkillConfigs.Add(200302,new TbsSkillConfig//技能近战2003
            {
                id = 200302,
                attackRange = 1f,
                moveToSpeed = 2,
                moveToDelayFrame = 0,
                moveToFrame = 33,
                moveBackSpeed = 2,
                moveBackFrame = 32,
                storageFrame = 0,
                moveBackDelayFrame = 1,
                moveBackStayFrame = 11,
                castFrame = 39,
                recoverFrame = 0,
                moveType = 1,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(4,100001,0),
                    new Vector3(13,100001,0),
                    new Vector3(28,100001,0),
                    new Vector3(28,800006,0),
                    //new Vector3(25,100002,0),
                    //new Vector3(25,800002,0),
                },
            });
            tbsSkillConfigs.Add(2001,new TbsSkillConfig//技能三连击
            {
                id = 2001,
                name = "三连击",
                attackRange = 2f,
                storageFrame = 5,
                castFrame = 35,
                recoverFrame = 10,
                moveType = 2,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(18,200001,0),
                    new Vector3(23,200001,0),
                    new Vector3(28,200001,0),
                },
                //blackScreen = 1,
            });
            tbsSkillConfigs.Add(2002,new TbsSkillConfig//被动技能 加攻击
            {
                id = 2002,
                name = "振奋",
                attackRange = 2f,
                storageFrame = 1,
                castFrame = 1,
                recoverFrame = 1,
                targetType = 1,
                targetSort = 0,
                targetNum = 1,
                triggerType = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(0,200011,0),
                },
            });
            tbsSkillConfigs.Add(2003,new TbsSkillConfig//被动技能 反击
            {
                id = 2003,
                name = "反击",
                attackRange = 2f,
                storageFrame = 1,
                castFrame = 1,
                recoverFrame = 1,
                targetType = 0,
                targetSort = 0,
                targetNum = 1,
                triggerType = 5,
                castEvent = new List<Vector3>
                {
                    new Vector3(0,200012,0),
                },
            });
            tbsSkillConfigs.Add(3001,new TbsSkillConfig//技能群体治疗
            {
                id = 3001,
                name = "群体治疗",
                attackRange = 2f,
                storageFrame = 5,
                castFrame = 35,
                recoverFrame = 10,
                moveType = 0,
                targetType = 1,
                targetNum = 6,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,300001,0),
                },
            });
            tbsSkillConfigs.Add(4001,new TbsSkillConfig//技能纵列
            {
                id = 4001,
                name = "纵列攻击",
                attackRange = 2f,
                storageFrame = 5,
                castFrame = 35,
                recoverFrame = 10,
                moveType = 2,
                targetType = 0,
                targetNum = 2,
                targetSort = 3,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,400001,0),
                },
            });
            tbsSkillConfigs.Add(5001,new TbsSkillConfig//技能后排
            {
                id = 5001,
                name = "后排攻击",
                attackRange = 2f,
                storageFrame = 5,
                castFrame = 35,
                recoverFrame = 10,
                moveType = 2,
                targetType = 0,
                targetSort = 5,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,500001,0),
                },
            });
            tbsSkillConfigs.Add(6001,new TbsSkillConfig//技能全体
            {
                id = 6001,
                name = "扫射",
                attackRange = 2f,
                storageFrame = 5,
                castFrame = 35,
                recoverFrame = 10,
                moveType = 0,
                targetType = 0,
                targetSort = 0,
                targetNum = 6,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,600001,0),
                },
            });
            tbsSkillConfigs.Add(7001,new TbsSkillConfig//技能突袭
            {
                id = 7001,
                name = "突袭",
                attackRange = 0.3f,
                storageFrame = 5,
                castFrame = 35,
                recoverFrame = 10,
                moveType = 1,
                targetType = 0,
                targetSort = 1,
                targetNum = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(25,700001,0),
                },
            });
            tbsSkillConfigs.Add(10001,new TbsSkillConfig
            {
                id = 10001,
                name = "触发冻伤",
                storageFrame = 1,
                castFrame = 1,
                recoverFrame = 1,
                moveType = 0,
                targetType = 0,
                targetNum = 1,
                targetSort = 0,
                type = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(0,800011,0),
                },
            });
            tbsSkillConfigs.Add(10002,new TbsSkillConfig
            {
                id = 10002,
                name = "触发爆炸",
                storageFrame = 0,
                castFrame = 10,
                recoverFrame = 0,
                moveType = 0,
                targetType = 0,
                targetNum = 5,
                targetSort = 0,
                type = 1,
                castEvent = new List<Vector3>
                {
                    new Vector3(3,800012,0),
                },
                effectEvent = new List<Vector3>
                {
                    new Vector3(3,10,0),
                },
            });
            PreloadTbsSkillPlayerConfigs();
        }

        private static void PreloadTbsSkillPlayerConfigs()
        {
            tbsSkillPlayerConfigs = new Dictionary<int, TbsSkillPlayerConfig>();
            #if UNITY_EDITOR
            foreach (var item in tbsSkillConfigs)
            {
                string path = string.Format("Assets/Arts/Pve/HeroSkill{1}.txt",0,item.Key);
                var text = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
                if (text != null && text.text != null)
                {
                    List<SkillPlayerActionFrame> actionList = new List<SkillPlayerActionFrame>();
                    List<SkillPlayerEventFrame> eventList = new List<SkillPlayerEventFrame>();
                    List<SkillPlayerMoveFrame> moveList = new List<SkillPlayerMoveFrame>();
                    var parts = text.text.Split(';');
                    for (int i = 0; i < parts.Length; i++)
                    {
                        var name = parts[i].Split(':');
                        if (name[0] == "Actions")
                        {
                            var actions = name[1].Split('\n');
                            for (int j = 0; j < actions.Length; j++)
                            {
                                var temp = actions[j].Split('|');
                                if (temp.Length > 1)
                                {
                                    int frame;
                                    int.TryParse(temp[0], out frame);
                                    actionList.Add(new SkillPlayerActionFrame
                                    {
                                        actionName = temp[1],
                                        frame = frame,
                                    });
                                }
                            }
                        }
                        else if (name[0].Contains("Events"))
                        {
                            var events = name[1].Split('\n');
                            for (int j = 0; j < events.Length; j++)
                            {
                                var temp = events[j].Split('|');
                                if (temp.Length > 1)
                                {
                                    int frame;
                                    int.TryParse(temp[0], out frame);
                                    int elementId;
                                    int.TryParse(temp[1], out elementId);
                                    eventList.Add(new SkillPlayerEventFrame
                                    {
                                        elementId = elementId,
                                        frame = frame,
                                    });
                                }
                            }
                        }
                        else if (name[0].Contains("Moves"))
                        {
                            var moves = name[1].Split('\n');
                            for (int j = 0; j < moves.Length; j++)
                            {
                                var temp = moves[j].Split('|');
                                if (temp.Length > 1)
                                {
                                    int frame;
                                    int.TryParse(temp[0], out frame);

                                    var v3 = temp[1].Substring(1, temp[1].Length - 2);
                                    var temp2 = v3.Split(',');
                                    float x;
                                    float.TryParse(temp2[0], out x);
                                    float y;
                                    float.TryParse(temp2[1], out y);
                                    float z;
                                    float.TryParse(temp2[2], out z);
                                    moveList.Add(new SkillPlayerMoveFrame
                                    {
                                        frame = frame,
                                        position = new Vector3(x,y,z),
                                    });
                                }
                            }
                        }
                    }

                    var skillPlayerConfig = new TbsSkillPlayerConfig
                    {
                        id = item.Key,
                        actions = actionList,
                        events = eventList,
                        moves = moveList,
                    };
                    tbsSkillPlayerConfigs.Add(item.Key,skillPlayerConfig);
                }
            }
            #endif
        }

        /*public static RpgLevelConfig GetRpgLevelConfig(int id)
        {
            if (rpgLevelConfigs == null)
            {
                PreloadRpgLevelConfig();
            }

            if (rpgLevelConfigs.TryGetValue(id, out var table))
            {
                return table;
            }

            return default;
        }*/

        /*public static Vector3 GetRpgObstacleSize(int id)
        {
            if (rpgObstacleBasics == null)
            {
                PreloadRpgLevelConfig();
            }

            if (rpgObstacleBasics.TryGetValue(id, out var table))
            {
                return table.size;
            }
            return new Vector3(1,1,1);
        }*/

        /*private static void PreloadRpgLevelConfig()
        {
            rpgObstacleBasics = new Dictionary<int, RpgObstacleBasic>();
            rpgObstacleBasics.Add(100,new RpgObstacleBasic
            {
                id = 100,
                size = new Vector3(2.5f,0,0.9f),
            });
            rpgObstacleBasics.Add(1,new RpgObstacleBasic
            {
                id = 101,
                size = new Vector3(1,0,0.3f),
            });
            rpgObstacleBasics.Add(2,new RpgObstacleBasic
            {
                id = 102,
                size = new Vector3(1,0,0.3f),
            });
            float tempLevelGap = 20;
            rpgLevelConfigs = new Dictionary<int, RpgLevelConfig>();
            rpgLevelConfigs.Add(1,new RpgLevelConfig
            {
                levelId = 1,
                stages = new List<RpgStageConfig>
                {
                    new RpgStageConfig
                    {
                        stageId = 0,
                        playerBirthPositions = new List<Vector3>
                        {
                            new Vector3(-5,0,0),
                            new Vector3(-7.5f,0,-5),
                            new Vector3(-7.5f,0,5),
                            new Vector3(-8f, 0, 0),
                        },
                        enemyBirthPositions = new List<Vector3>
                        {
                            new Vector3(4,0,0),
                            new Vector3(7.5f,0,-5),
                            new Vector3(7.5f,0,5),
                            new Vector3(8f, 0, 0),
                        },
                        obstacles = new List<RpgObstacleConfig>
                        {
                            new RpgObstacleConfig
                            {
                                basic = rpgObstacleBasics[0],
                                position = new Vector3(0,0,0),
                                rotation = Vector3.zero,
                                hidePoint = new Vector3(-1,0,0),
                                scale = new Vector3(1,1,1),
                            },
                            new RpgObstacleConfig
                            {
                                basic = rpgObstacleBasics[1],
                                position = new Vector3(-4,0,2),
                                rotation = Vector3.zero,
                                hidePoint = new Vector3(-4.7f,0,2),
                                scale = new Vector3(1,1,1),
                            },
                            new RpgObstacleConfig
                            {
                                basic = rpgObstacleBasics[2],
                                position = new Vector3(-4,0,-2),
                                rotation = Vector3.zero,
                                hidePoint = new Vector3(-4.7f,0,-2),
                                scale = new Vector3(1,1,1),
                            }
                        }
                    },
                    new RpgStageConfig
                    {
                        stageId = 1,
                        playerBirthPositions = new List<Vector3>
                        {
                            new Vector3(-5 + tempLevelGap,0,0),
                            new Vector3(-7.5f + tempLevelGap,0,-5),
                            new Vector3(-7.5f + tempLevelGap,0,5),
                            new Vector3(-8f + tempLevelGap, 0, 0),
                        },
                        enemyBirthPositions = new List<Vector3>
                        {
                            new Vector3(4 + tempLevelGap,0,0),
                            new Vector3(7.5f + tempLevelGap,0,-5),
                            new Vector3(7.5f + tempLevelGap,0,5),
                            new Vector3(8f + tempLevelGap, 0, 0),
                        },
                        obstacles = new List<RpgObstacleConfig>
                        {
                            new RpgObstacleConfig
                            {
                                basic = rpgObstacleBasics[0],
                                position = new Vector3(0 + tempLevelGap,0,0),
                                rotation = Vector3.zero,
                                hidePoint = new Vector3(-1 + tempLevelGap,0,0),
                                scale = new Vector3(1,1,1),
                            },
                            new RpgObstacleConfig
                            {
                                basic = rpgObstacleBasics[1],
                                position = new Vector3(-4 + tempLevelGap,0,2),
                                rotation = Vector3.zero,
                                hidePoint = new Vector3(-4.7f + tempLevelGap,0,2),
                                scale = new Vector3(1,1,1),
                            },
                            new RpgObstacleConfig
                            {
                                basic = rpgObstacleBasics[2],
                                position = new Vector3(-4 + tempLevelGap,0,-2),
                                rotation = Vector3.zero,
                                hidePoint = new Vector3(-4.7f + tempLevelGap,0,-2),
                                scale = new Vector3(1,1,1),
                            }
                        }
                    },
                },
            });
        }*/


        private static void PreloadTbsSkillElementConfigs()
        {
            tbsElementConfigs = new Dictionary<int, TbsSkillElementConfig>();
            tbsElementConfigs.Add(100000, new TbsSkillElementConfig //普攻伤害元素
            {
                id = 100000,
                element_type = 1,
                output = 5,
                timeStop = 100,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 1,
                },
            });
            tbsElementConfigs.Add(100001, new TbsSkillElementConfig //普工伤害元素 我方
            {
                id = 100001,
                element_type = 1,
                output = 10,
                timeStop = 100,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 1,
                },
            });
            tbsElementConfigs.Add(100002, new TbsSkillElementConfig //普工击飞 我方
            {
                id = 100002,
                element_type = 4,
                flyText = "击飞",
                element_param = new Dictionary<string, int>()
                {
                    ["CombineType"] = 1,
                    ["LastTime"] = 800,
                },
            });
            tbsElementConfigs.Add(100003, new TbsSkillElementConfig //普工击飞 我方
            {
                id = 100003,
                element_type = 4,
                //flyText = "击飞",
                element_param = new Dictionary<string, int>()
                {
                    ["CombineType"] = 4,
                    ["LastTime"] = 300,
                },
            });
            tbsElementConfigs.Add(200001, new TbsSkillElementConfig //技能三连击 元素
            {
                id = 200001,
                element_type = 1,
                output = 10,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(300001, new TbsSkillElementConfig //技能全体治疗 元素
            {
                id = 300001,
                element_type = 1,
                output = 10,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 3,
                }
            });
            tbsElementConfigs.Add(400001, new TbsSkillElementConfig //技能纵列 元素
            {
                id = 400001,
                element_type = 1,
                output = 30,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(500001, new TbsSkillElementConfig //技能后排 元素
            {
                id = 500001,
                element_type = 1,
                output = 30,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(600001, new TbsSkillElementConfig //技能全体 元素
            {
                id = 600001,
                element_type = 1,
                output = 20,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(700001, new TbsSkillElementConfig //技能纵列 元素
            {
                id = 700001,
                element_type = 1,
                output = 40,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(200011, new TbsSkillElementConfig //元素加攻击
            {
                id = 200011,
                element_type = 2,
                output = 2000,
                flyText = "攻击力上升",
                element_param = new Dictionary<string, int>()
                {
                    ["AttributeID"] = 1,
                    ["CalculateType"] = 3,
                    ["LastTime"] = 1,
                },
            });
            tbsElementConfigs.Add(200012, new TbsSkillElementConfig //我方 反击元素
            {
                id = 200012,
                element_type = 1,
                output = 10,
                timeStop = 100,
                element_param = new Dictionary<string, int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(800001, new TbsSkillElementConfig //元素 湿身
            {
                id = 800001,
                element_type = 4,
                flyText = "水",
                element_param = new Dictionary<string, int>()
                {
                    ["CombineType"] = 2,
                    ["LastRound"] = 1,
                },
            });
            tbsElementConfigs.Add(800002, new TbsSkillElementConfig //元素 冷气
            {
                id = 800002,
                element_type = 4,
                flyText = "冰",
                element_param = new Dictionary<string, int>()
                {
                    ["CombineType"] = 3,
                    ["LastRound"] = 1,
                },
            });
            tbsElementConfigs.Add(800003, new TbsSkillElementConfig //元素 电
            {
                id = 800003,
                element_type = 4,
                combineType = 4,
                flyText = "电",
                //rgb = new Vector3(1,1,0),
                //rgbIntensity = 0.6f,
                effectId = 800003,
                element_param = new Dictionary<string, int>()
                {
                    ["ControlType"] = 2,
                    ["LastRound"] = 2,
                },
            });
            tbsElementConfigs.Add(800004, new TbsSkillElementConfig //元素 火
            {
                id = 800004,
                element_type = 3,
                combineType = 5,
                flyText = "火",
                rgb = new Vector3(1, 0, 0),
                rgbIntensity = 0.7f,
                //effectId = 800004,
                element_param = new Dictionary<string, int>()
                {
                    ["LastRound"] = 2,
                    ["TriggerElement"] = 800013,
                    ["TriggerType"] = 1,
                },
            });
            tbsElementConfigs.Add(800005, new TbsSkillElementConfig //元素 毒
            {
                id = 800005,
                element_type = 3,
                combineType = 6,
                flyText = "毒",
                element_param = new Dictionary<string, int>()
                {
                    ["LastRound"] = 2,
                    ["TriggerElement"] = 800014,
                    ["TriggerType"] = 2,
                },
            });
            tbsElementConfigs.Add(800006, new TbsSkillElementConfig //元素 流血
            {
                id = 800006,
                element_type = 3,
                combineType = 7,
                flyText = "流血",
                effectId = 800006,
                element_param = new Dictionary<string, int>()
                {
                    ["LastRound"] = 2,
                    ["TriggerElement"] = 800015,
                    ["TriggerType"] = 5,
                },
            });

            tbsElementConfigs.Add(800011,new TbsSkillElementConfig//元素 冻伤
            {
                id = 800011,
                element_type = 3,
                flyText = "冻伤",
                element_param = new Dictionary<string,int>()
                {
                    ["LastRound"] = 1,
                    ["ControlType"] = 1,
                },
            });
            tbsElementConfigs.Add(800012,new TbsSkillElementConfig//元素 爆炸
            {
                id = 800012,
                element_type = 1,
                output = 50,
                flyText = "爆炸",
                element_param = new Dictionary<string,int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(800013,new TbsSkillElementConfig//元素 烧伤
            {
                id = 800013,
                element_type = 1,
                output = 10,
                flyText = "烧伤",
                element_param = new Dictionary<string,int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(800014,new TbsSkillElementConfig//元素 中毒
            {
                id = 800014,
                element_type = 1,
                output = 10,
                flyText = "中毒",
                element_param = new Dictionary<string,int>()
                {
                    ["OutputType"] = 2,
                },
            });
            tbsElementConfigs.Add(800015,new TbsSkillElementConfig//元素 出血伤害
            {
                id = 800015,
                element_type = 1,
                output = 10,
                flyText = "出血",
                element_param = new Dictionary<string,int>()
                {
                    ["OutputType"] = 2,
                },
            });
        }

        public static int[] UseHasTableToNonRepeatedRandom(int length, int minValue, int maxValue)
        {
            if (length > maxValue - minValue)
            {
                return null;
            }
            Hashtable hashtable = new Hashtable();
            for (int i = 0; hashtable.Count<length; i++)
            {
                int nValue = Random.Range(minValue, maxValue);
                if (!hashtable.ContainsValue(nValue))
                {
                    hashtable.Add(i, nValue);
                }
            }

            int[] array = new int[hashtable.Count];
            hashtable.Values.CopyTo(array, 0);
            return array;
        }

     
    }
}
